package stream源码分析.ﬁlter.PredicateTest.FunctionTest;

import java.util.function.Function;

public class FunctionDemo {
    public static void main(String[] args) {
//        applyTest();
        composeTest();
    }
    public static void applyTest(){
        Function<Integer,String> intToString=e->e*e+"";
        System.out.println(intToString.apply(2));
    }
    public static void composeTest(){
        Function<String, String> times2 = e -> e+"times2";

        Function<String, String> squared = e -> e +"squared";

        // 先执行参数，再执行调用者
        /*
         * 1. 4 * 4 = 16 16 * 2 = 32
         */
        System.out.println("result: " + times2.compose(squared).apply("1")); // 32

        /*
         * 先执行调用者： 4 * 2 = 8 再执行then传入的function 8 * 8 = 64
         */
        System.out.println("result: " + times2.andThen(squared).apply("2")); // 64

    }
}
/**
 * Function＜T,R＞接口
 * 在jdk8以后Java中可以像JavaScript那样，把一个函数直接当做参数来传递
 * 从Java 8开始，是可以的。在Java提供的函数式编程接口中
 * Function<T,R>接口的作用的是用来表现一个参数类型为T、返回值类型为R的函数（方法）。
 * 方法详解:
 * 1. R apply(T t)
 *  将此函数应用于给定的参数。
 *  形参: T – the function argument 函数自变量
 *  返回值:R – the function result 函数结果
 *  以    Function<Integer,String> intToString=e->e*e+""; 为例
 *  intToString.intToString.apply(2)==2*2+"";
 * 相当于将T作为参数执行Function里面的代码,最终返回结果
 * 2.<V> Function<V, R> compose(Function<? super V, ? extends T> before)
 * 先执行参数，再执行调用者
 * 根据代码的执行优先级(参考)
 *
 */
